#if !defined(MGCFG_H_INCLUDED)
#define MGCFG_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#pragma warning(push) 
#pragma warning(disable: 4786)

// forward reference
template<class TAction, class TList, class TOption>
class CMGCfg;

#include "MGActionImpl.h"
#include "MGListImpl.h"
#include "MGOptionImpl.h"

#include "SSMutex.h"

typedef CMGCfg<CMGAction<>, CMGList<GESTURE>, CMGOption<> > MGCfg;
//	typedef CMGCfg<CMGAction<CustomMGActionImpl>, CMGList<GestureStruct, CustomMGListImpl>, CMGOption<CustomMGOptionImpl> > MGCfg;

template<class TAction, class TList, class TOption>
class CMGCfg  
{
	typedef CMGCfg<TAction, TList, TOption> CMGCFG;

	friend class SSMutexT<CMGCFG>;

public:
	/// singleton access function
	static CMGCfg &Get()
	{
		return *( SSMutexT<CMGCFG>::Instance() );
	}

	/// singleton cleanup function
	static void Cleanup()
	{
		CMGCFG &rMGCfg = CMGCFG::Get();
		rMGCfg.List().Cleanup();	/// simply free the memory that was allocated for storing the list of MG and it's associated command
		rMGCfg.Action().Cleanup();
		rMGCfg.Option().Cleanup();
	}

public:
	TOption &Option()
	{
		if(m_pOption == NULL)
			m_pOption = new TOption;

		return *m_pOption;
	}

	TAction &Action()
	{
		if(m_pAction == NULL)
			m_pAction = new TAction;

		return *m_pAction;
	}

	TList &List()
	{
		if(m_pList == NULL)
			m_pList = new TList;

		return *m_pList;
	}

	// overrides
public:
	virtual void UpdateRegistry(BOOL bSaveAndValidate = TRUE)
	{
		Option().UpdateRegistry(bSaveAndValidate);
		List().UpdateRegistry(bSaveAndValidate);
		Action().UpdateRegistry(bSaveAndValidate);
	}

protected:
	/// It is only allowed to be created/deleted within SSMutexT<CMGCfg> class's scope
	CMGCfg() : m_pOption(NULL), m_pAction(NULL), m_pList(NULL)
	{
		UpdateRegistry(FALSE);
	}

	virtual ~CMGCfg()
	{
		regbool rgbAutoloadingOnStartup(SECTION KEY15, HKEY_CURRENT_USER);
		regbool rgbMouseGestureEnabled(SECTION KEY01, HKEY_CURRENT_USER);
		rgbMouseGestureEnabled = (BOOL)rgbAutoloadingOnStartup;
		
		delete m_pOption;
		delete m_pAction;
		delete m_pList;
	}

private:
	TOption	*m_pOption;
	TAction	*m_pAction;
	TList	*m_pList;
};

#pragma warning(pop) 

#endif // !defined(MGCFG_H_INCLUDED)
